package net.lesscoding.rpc.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import net.lesscoding.common.Const;
import net.lesscoding.protocol.ProtocolFrameDecoder;
import net.lesscoding.protocol.SharedMessageCodec;
import net.lesscoding.rpc.handler.RpcResponseMessageHandler;
import net.lesscoding.rpc.message.RpcRequestMessage;

/**
 * @author eleven
 * @date 2024/12/4 8:39
 * @apiNote
 */
@Slf4j
public class RpcClient {
    public static void main(String[] args) {
        LoggingHandler loggingHandler = new LoggingHandler();
        SharedMessageCodec messageCodec = new SharedMessageCodec();
        NioEventLoopGroup group = new NioEventLoopGroup();
        RpcResponseMessageHandler rpcResponseMessageHandler = new RpcResponseMessageHandler();
        try {
            Bootstrap bootstrap = new Bootstrap()
                    .group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) throws Exception {
                            ch.pipeline()
                                    .addLast(new ProtocolFrameDecoder())
                                    .addLast(loggingHandler)
                                    .addLast(messageCodec)
                                    .addLast(rpcResponseMessageHandler);
                        }
                    });
            Channel channel = bootstrap.connect(Const.HOST, Const.PORT).sync().channel();
            ChannelFuture channelFuture = channel.writeAndFlush(new RpcRequestMessage(
                    1,
                    "net.lesscoding.rpc.service.HelloService",
                    "sayHello",
                    String.class,
                    new Class[]{String.class},
                    new Object[]{"Listen"}
            ));
            channelFuture.addListener(promise -> {
                if (!promise.isSuccess()) {
                    Throwable cause = promise.cause();
                    log.error("发生错误：", cause);
                }
            });
            ChannelFuture future = channel.closeFuture().sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            group.shutdownGracefully();
        }
    }
}
